//
//  TYMenuListViewController.m
//  TYUIKit
//
//  Created by TuyaInc on 2019/12/5.
//

#import "TYMenuListViewController.h"

#import "TYHitTestView.h"
#import "UIScreen+TYFrame.h"
#import "UIView+TYFrame.h"

@interface TYMenuListBackgroundView : UIView
@property (nonatomic, copy) dispatch_block_t touchHandler;
@end

@implementation TYMenuListBackgroundView

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    if (self.touchHandler) {
        self.touchHandler();
    }
    [super touchesBegan:touches withEvent:event];
}

@end

static NSString * const kTYMenuListCellIdentifierDefault = @"kTYMenuListCellIdentifierDefault";

@interface TYMenuListViewController () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) TYHitTestView *containerView;
@property (nonatomic, strong) TYMenuListBackgroundView *backgroundView;

@property (nonatomic, strong) NSMutableDictionary *menuCellClassMap;

@end

@implementation TYMenuListViewController


- (instancetype)init {
    if (self = [super init]) {
        _makeAnchorPointFollowIndicator = YES;
        _statusBarHidden = NO;
        _autorotate = NO;
        _supportedOrientations = UIInterfaceOrientationMaskPortrait;
        _menuCellClassMap = [NSMutableDictionary new];
        _statusBarAnimation = UIStatusBarAnimationNone;
        _statusBarStyle = UIStatusBarStyleDefault;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
        
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    [self.view addSubview:self.backgroundView];
    [self.view addSubview:self.containerView];

    [self setupIndicator];
    [self setupMenu];
    [self updateAnchorIfNeed];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    if (_indicatorView && _indicatorView.superview == self.containerView) {
        // 一些待开发的功能
    }
    
    if (_menuView && _automaticMenuHeight && _menuView.frame.size.width > 0) {
        _menuView.ty_height = [UIScreen mainScreen].bounds.size.height;
        CGFloat height = 0;
        for (NSInteger section = 0; section < _menuView.numberOfSections; section ++) {
            for (NSInteger row = 0; row < [_menuView numberOfRowsInSection:section]; row ++) {
                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
                UITableViewCell *cell = [_menuView cellForRowAtIndexPath:indexPath];
                height += cell.frame.size.height;
            }
        }
        _menuView.ty_height = height;
    }
}

- (void)setupMenu {
    [self registMenuCell];
    
    if (self.menuView.superview != self.containerView) {
        [self.containerView addSubview:self.menuView];
    }
}

- (void)setupIndicator {
    if (!_indicatorView) {
        return;
    }
    if (_indicatorView.superview != self.containerView) {
        [self.containerView insertSubview:_indicatorView belowSubview:_menuView];
    }
}

- (void)updateAnchorIfNeed {
    if (!_indicatorView || !_makeAnchorPointFollowIndicator) {
        return;
    }
    static BOOL waitingForUpdate;
    if (waitingForUpdate) {
        return;
    }
    waitingForUpdate = YES;
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        waitingForUpdate = NO;
        [weakSelf updateContainerAnchorPoint];
    });
}

- (void)updateContainerAnchorPoint {
    if (_indicatorView && _makeAnchorPointFollowIndicator) {
        CGPoint positionOld = _containerView.layer.position;
        CGPoint anchorPointOld = _containerView.layer.anchorPoint;
        
        CGPoint anchorTarget = _indicatorView.center;
        CGFloat xValue = _indicatorView.center.x - _menuView.center.x;
        CGFloat yValue = _indicatorView.center.y - _menuView.center.y;
        
        /*
         用menu的四条边，将空间划为9块，其中0为Menu
         1 |  2  | 3
         --|-----|——
         4 |  0  | 5
         --|-----|——
         6 |  7  | 8
        */
        
        
        // 指示器在 1、4、6 或 3、5、8 （左负右正）
        if (fabs(xValue) > _menuView.bounds.size.width/2.0) {
            // 符号 * 指示器宽度的一半
            anchorTarget.x += (xValue/fabs(xValue) * _indicatorView.bounds.size.width/2.0);
        }
        // 指示器在 1、2、3 或 6、7、8 （上负下正）
        if (fabs(yValue) > _menuView.bounds.size.height/2.0) {
            // 符号 * 指示器高度的一半
            anchorTarget.y += (yValue/fabs(yValue) * _indicatorView.bounds.size.height/2.0);
        }
        
        CGPoint anchorPoint = CGPointMake(anchorTarget.x/_containerView.bounds.size.width, anchorTarget.y/_containerView.bounds.size.height);
        
        _containerView.layer.anchorPoint = anchorPoint;
        
        // 还原位置
        _containerView.layer.position = CGPointMake(positionOld.x + (anchorPoint.x - anchorPointOld.x) * _containerView.bounds.size.width, positionOld.y + (anchorPoint.y - anchorPointOld.y) * _containerView.bounds.size.height);
    }
}

- (void)registMenuCell {
    if (_menuCellClassArr) {
        __weak typeof(self) weakSelf = self;
        [_menuCellClassArr enumerateObjectsUsingBlock:^(Class<TYMenuListCellProtocol>  _Nonnull cls, NSUInteger idx, BOOL * _Nonnull stop) {
            NSString *identifier = [cls respondsToSelector:@selector(menuCellIdentifier)] ? [cls menuCellIdentifier] : NSStringFromClass(cls);
            [weakSelf.menuView registerClass:cls forCellReuseIdentifier:identifier];
            [weakSelf.menuCellClassMap setValue:cls forKey:identifier];
            if (idx == 0) {
                [weakSelf.menuView registerClass:cls forCellReuseIdentifier:kTYMenuListCellIdentifierDefault];
                [weakSelf.menuCellClassMap setValue:cls forKey:kTYMenuListCellIdentifierDefault];
            }
        }];
    }
}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([_delegate respondsToSelector:@selector(ty_menuList:didSelectRowAtIndexPath:)]) {
        [_delegate ty_menuList:self didSelectRowAtIndexPath:indexPath];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (_menuDataArr == nil || _menuDataArr.count == 0) {
        return 0;
    }
    id<TYMenuListDataProtocol> data = _menuDataArr[indexPath.row];
    NSString *identifier = [data respondsToSelector:@selector(menuReusableCellIdentifier)] ? [data menuReusableCellIdentifier] : kTYMenuListCellIdentifierDefault;
    Class<TYMenuListCellProtocol> cellCls = _menuCellClassMap[identifier];
    return [cellCls respondsToSelector:@selector(menuCellHeightForData:)] ? [cellCls menuCellHeightForData:data] : UITableViewAutomaticDimension;
}


#pragma mark - <UITableViewDataSource>
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _menuDataArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    id<TYMenuListDataProtocol> data = _menuDataArr[indexPath.row];
    NSString *identifier = [data respondsToSelector:@selector(menuReusableCellIdentifier)] ? [data menuReusableCellIdentifier] : kTYMenuListCellIdentifierDefault;
    UITableViewCell<TYMenuListCellProtocol> *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
    [cell setupMenuWithData:data];
    
    return cell;
}

#pragma mark - Action
- (void)menuListBackgroundTouchAction {
    if ([_delegate respondsToSelector:@selector(ty_menuListBackgroundTapAction:)]) {
        [_delegate ty_menuListBackgroundTapAction:self];
    }
}

#pragma mark - Accessor
- (UITableView *)menuView {
    if (!_menuView) {
        _menuView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _menuView.backgroundView.backgroundColor = [UIColor whiteColor];
        _menuView.separatorColor = [[UIColor blackColor] colorWithAlphaComponent:0.1];
        _menuView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
        _menuView.showsHorizontalScrollIndicator = NO;
        _menuView.showsVerticalScrollIndicator = NO;
        _menuView.alwaysBounceHorizontal = NO;
        _menuView.alwaysBounceVertical = NO;
        _menuView.layer.masksToBounds = YES;
        _menuView.layer.cornerRadius = 8;
        _menuView.dataSource = self;
        _menuView.delegate = self;
        if (@available(iOS 11.0, *)) {
            _menuView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
    }
    return _menuView;
}

- (TYMenuListBackgroundView *)backgroundView {
    if (!_backgroundView) {
        _backgroundView = [[TYMenuListBackgroundView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _backgroundView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.2];
        __weak typeof(self) weakSelf = self;
        _backgroundView.touchHandler = ^{
            [weakSelf menuListBackgroundTouchAction];
        };
    }
    return _backgroundView;
}

- (UIView *)containerView {
    if (!_containerView) {
        _containerView = [[TYHitTestView alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _containerView.layer.shadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.1].CGColor;
        _containerView.layer.shadowOffset = CGSizeMake(0, 4);
        _containerView.layer.shadowRadius = 8;
        _containerView.layer.shadowOpacity = 1;
        __weak typeof(self) weakSelf = self;
        _containerView.ty_pointInsideBlock = ^BOOL(CGPoint point, UIEvent * _Nonnull event, BOOL defaultResult) {
            return CGRectContainsPoint(weakSelf.menuView.bounds, [weakSelf.menuView convertPoint:point fromView:weakSelf.containerView]);
        };
    }
    return _containerView;
}

- (void)setIndicatorView:(UIView *)indicatorView {
    [_indicatorView removeFromSuperview];
    _indicatorView = indicatorView;
    if (self.isViewLoaded) {
        [self setupIndicator];
        [self updateAnchorIfNeed];
    }
}

- (void)setMenuDataArr:(NSArray *)menuDataArr {
    _menuDataArr = menuDataArr.copy;
    if (self.isViewLoaded) {
        [_menuView reloadData];
    }
}

- (void)setMenuCellClassArr:(NSArray<Class<TYMenuListCellProtocol>> *)menuCellClassArr {
    _menuCellClassArr = menuCellClassArr;
    if (self.isViewLoaded) {
        [self registMenuCell];
    }
}

#pragma mark - StatusBar
- (BOOL)prefersStatusBarHidden {
    return _statusBarHidden;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
    return _statusBarStyle;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return _statusBarAnimation;
}

#pragma mark - Orientation
- (BOOL)shouldAutorotate {
    return _autorotate;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return _supportedOrientations;
}

@end
